package com.example.gateway.filter;

import com.egreen.common.serviceapi.admin.IAdminCheckJwtApi;
import com.egreen.common.serviceapi.user.IJwtServiceApi;
import com.egreen.user.exceptions.JwtFormatException;
import com.egreen.user.exceptions.JwtNotFoundException;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;

@Slf4j
@Component//注入组件中
@Order(-1)//过滤器执行顺序，值越大顺序越慢
public class JwtCheckFilter implements GlobalFilter {
    @DubboReference
    IJwtServiceApi jwtServiceApi;
    @DubboReference
    IAdminCheckJwtApi checkJwtApi;
    /**
     * @param exchange  请求上下文，里面可以获取Request,Response等信息
     * @param chain   用来把请求委托给下一个过滤器
     * @return {@code Mono<void>返回标示当前过滤器业务结束}
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("进行请求的判断是否需要放行");
        ServerHttpRequest request = exchange.getRequest();
        log.info("输出的uri:{}", request.getURI().getPath());
        if (request.getURI().getPath().contains("/signUp") ||
                request.getURI().getPath().contains("/loginByPassword") ||
                request.getURI().getPath().contains("/loginByValidCode") ||
                request.getURI().getPath().contains("/adminLogin") ||
                request.getURI().getPath().contains("/sendCode") ||
                request.getURI().getPath().contains("/doc.html") ||
                request.getURI().getPath().contains("/v2/api-docs") ||
                request.getURI().getPath().contains("/productCategory")||
                request.getURI().getPath().contains("/swagger-resources") ||
                request.getURI().getPath().contains("/webjars")
        ) {
            log.info("放行!");
            return chain.filter(exchange);
        }
        /**
         * 管理员请求的验证
         */
        if (request.getURI().getPath().contains("/admin")) {
            log.info("获取管理员token");
            String token = request.getHeaders().getFirst("Token");
            if (token == null) {
                throw new JwtNotFoundException();
            }

            try {
                checkJwtApi.checkAdminJwt(token);
            } catch (Exception e) {
                e.printStackTrace();
                throw new JwtFormatException();
            }

            Object clamis = checkJwtApi.checkAdminJwt(token);
            HashMap<String, Integer> user = (HashMap<String, Integer>) clamis;
            Integer userRole = user.get("adminRole");
            log.info("该请求为管理员模块请求");
            log.info("开始判断管理员身份");
            if (userRole == 7 || userRole == 8) {
                if (request.getURI().getPath().contains("/queryOperationRecord")) {
                    log.info("操作为查看记录，需要超级管理员权限！");
                    if (userRole == 8) {
                        log.info("该用户为超级管理员,放行！");
                        return chain.filter(exchange);
                    } else {
                        log.info("该用户不是超级管理员，无法访问");
                        throw new UnsupportedOperationException();
                    }
                }
                log.info("身份为管理员，放行！");
                return chain.filter(exchange);
            }
            log.info("该用户不是管理员，无法访问！");
            throw new UnsupportedOperationException();
        }
        /**
         * 普通请求的验证
         */
        log.info("该请求为普通用户");
        log.info("获取用户token");
        String token = request.getHeaders().getFirst("Token");
        log.info("Token为:{}", token);
        if (token == null || token.equals("")) {
            log.info("该请求不含token，阻拦！");
            throw new JwtNotFoundException();
        }
        log.info("该请求含有token，进行判断token是否正确");
        try {
            checkJwtApi.checkAdminJwt(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new JwtFormatException();
        }
        Object claims = jwtServiceApi.checkJwt(token);
        if (claims != null) {
            log.info("验证成功，放行！");
            return chain.filter(exchange);
        }

        //拦截
        //1.为了用户体验，设置状态码，让用户看起来比较好,unauthorized未登录
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        //2.拦截请求
        return exchange.getResponse().setComplete();
    }

}
